# from .fake import *
import traceback

from rbtools.api.client import RBClient
from rbtools.api.errors import AuthorizationError
from review.models import *

# API reference: https://www.reviewboard.org/docs/rbtools/2.0/api/#rbtools-api
# Tutorial: https://www.reviewboard.org/docs/rbtools/2.0/api/tutorial/
from review.util.util import push_kwargs


def review_client():
    return RBClient(url=settings.REVIEW_BOARD_URL)


def review_root(client=None):
    if not client:
        client = review_client()
    return client.get_root()


def get_people_name_name_tuple():
    # TODO: Check IT OK, then UN comment them
    # return [(p.username, p.username) for p in get_people_list()]
    return [('guest2838', 'guest2838'),
            ('g2', 'g2')]


def get_branch_name_name_tuple():
    return [
        ('dev_sunflower', 'dev_sunflower'),
        ('dev_sunflower_singlefw', 'dev_sunflower_singlefw'),
        ('dev_sunflower_des52', 'dev_sunflower_des52'),
    ]


def get_people_name_id_tuple():
    return [(p.id, p.username) for p in get_people_list()]


def get_people_name_list():
    # return [p.username for p in get_people_list()]
    return ['people1', 'people2', 'people3', 'people4', 'people5', 'people6', 'people7', 'people8', 'people9',
            'people10', 'people11']


def get_people_list():
    return review_root().get_users(max_results=500)


def get_group_name_name_tuple():
    # TODO: Check IT OK, then UN comment them
    # return [(g.display_name, g.display_name) for g in get_group_list()]
    return [
        ('demo', 'demo'),
        ('demo1', 'demo1'),
        ('demo2', 'demo2'),
        ('demo3', 'demo3'),
        ('demo4', 'demo4'),
        ('demo5', 'demo5'),
        ('demo6', 'demo6'),
        ('demo7', 'demo7'),
        ('demo8', 'demo8'),
        ('demo9', 'demo9'),
        ('demo10', 'demo10'),
        ('demo11', 'demo11'),
        ('demo12', 'demo12'),
        ('demo13', 'demo13'),
        ('demo14', 'demo14'),
        ('demo15', 'demo15'),
        ('demo16', 'demo16'),
        ('demo17', 'demo17'),
        ('demo18', 'demo18'),
        ('demo19', 'demo19'),
        ('demo20', 'demo20'),
    ]


def get_group_name_id_tuple():
    return [(g.id, g.display_name) for g in get_group_list()]


def get_group_name_list():
    # return [g.display_name for g in get_group_list()]
    return ['g1', 'g2', 'g3', 'g4', 'g5', 'g6', 'g7', 'g8', 'g9', 'g10', 'g11']


def get_group_list():
    return review_root().get_groups(max_results=200)


def get_repository_name_name_tuple():
    # TODO: Check IT OK, then UN comment them
    # return [(r.name, r.name) for r in get_repository_list()]
    return [('Review Board', 'Review Board'),
            ('second', 'second')]


def get_repository_name_id_tuple():
    return [(r.id, r.name) for r in get_repository_list()]


def get_repository_name_list():
    # return [r.name for r in get_repository_list()]
    return ['repo1', 'repo2', 'repo3', 'repo4', 'repo5', 'repo6', 'repo7', 'repo8', 'repo9', 'repo10', 'repo11']


def get_repository_list():
    return review_root().get_repositories(max_results=200)


class ReviewClient:
    def __init__(self, form_data: {}):
        self._data = form_data
        self._root = RBClient(
            url=settings.REVIEW_BOARD_URL,
            api_token=self.review_user.review_api_token,
            cookie_file=self.review_user.review_cookie_file.path,
        ).get_root()

    @property
    def public(self):
        return self._data['public']

    @property
    def bugs(self):
        return self._data['bugs']

    @property
    def review_user(self):
        return self._data['user'].reviewuser

    @property
    def review_repo(self):
        return self._data['review_profile'].review_repository

    @property
    def review_diff(self):
        return self._data['final_patch']

    @property
    def review_diff_contents(self):
        return self.review_diff.read() if self.review_diff else None

    @property
    def review_summary(self):
        return self._data['review_summary']

    @property
    def review_description(self):
        return self._data['review_description']

    @property
    def review_testing_done(self):
        return self._data['review_testing_done']

    @property
    def review_branch(self):
        return self._data['review_branch']

    @property
    def review_target_people(self):
        return self._data['review_target_people']

    @property
    def review_target_groups(self):
        return self._data['review_target_groups']

    @property
    def review_change_description(self):
        return self._data['review_change_description']

    @property
    def review_id(self):
        return self._data['review_id']

    def remote_repo(self):
        return self._root.get_repositories(name=self.review_repo)[0].id

    @property
    def base_kwargs(self) -> dict:
        return {
            'summary': self.review_summary,
            'description': self.review_description,
            'testing_done': self.review_testing_done,
            'branch': self.review_branch,
            'bugs_closed': self.bugs,
            'target_people': self.review_target_people,
            'target_groups': self.review_target_groups,
        }

    def get_ship_it_count(self, review_id):
        request = self._root.get_review_requests().get_item(pk=review_id)
        return request.ship_it_count

    def update_draft(self, public=True):
        if not self.review_id or self.review_id == 0:
            raise BaseException

        request = self._root.get_review_requests().get_item(pk=self.review_id)

        if self.review_diff:
            request.get_diffs().upload_diff(self.review_diff_contents)

        kwargs = {}
        push_kwargs(kwargs, self.base_kwargs)

        if self.public is True:
            push_kwargs(kwargs, {
                'changedescription': self.review_change_description,
            })

        draft = request.get_or_create_draft()
        draft = draft.update(**kwargs)
        if public:
            draft = draft.update(public=True)

        return draft, request

    def create_draft(self, public=False):
        """ return draft and request """
        request = self._root.get_review_requests().create(
            repository=self.remote_repo()
        )

        if self.review_diff:
            request.get_diffs().upload_diff(self.review_diff_contents)

        kwargs = {}
        push_kwargs(kwargs, self.base_kwargs)

        draft = request.get_or_create_draft()
        draft = draft.update(**kwargs)
        if public:
            draft = draft.update(public=True)

        return draft, request
